using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;

namespace commonV2.controls
{
    //From http://www.codeproject.com/Articles/18356/Word-Processor-Based-Upon-an-Extended-RichTextBox
    public partial class rtfEditor : commonV2.controls.baseUserControl
    {
        public rtfEditor()
        {
            InitializeComponent();
        }

        #region public
        public string myText
        {
            get
            {
                return rtbDoc.Rtf;
            }
            set
            {
                rtbDoc.Rtf =  value;
            }
        }
        public bool ReadOnly
        {
            get
            {
                return rtbDoc.ReadOnly;
            }
        }

        public void SetReadOnly(bool value)
        {
            LockEdit(value);
            SetMenuEnableLOCKED(value==false);
            lockEdMenuItem.Checked = value;
        }
        public void SetLocked(bool value)
        {
            LockEdit(value);
            lockEdMenuItem.Checked = value;
        }

        public void SetMenuEnableEXIT(bool enable)
        {
            ExitToolStripMenuItem.Enabled = enable;
        }
        public void SetMenuEnableLOCKED(bool enable)
        {
            lockEdMenuItem.Enabled = enable;
        }
        public void SetMenuEnableSAVE(bool enable)
        {
            SaveToolStripMenuItem.Enabled = enable;
            tbrSave.Enabled = enable;
        }

        public delegate bool OnProcess(object sender);
        public event OnProcess myOnExit = null;
        public event OnProcess myOnSave = null;

        public bool TextModified()
        {
            return rtbDoc.Modified;
        }
        public void AcceptTextModified()
        {
            rtbDoc.Modified = false;
        }
        #endregion

        private void LockEdit(bool locked)
        {
            bool enabled = !locked;
            rtbDoc.ReadOnly = locked;

            //Menu
            OpenToolStripMenuItem.Enabled = enabled;
            NewToolStripMenuItem.Enabled = enabled;
            SaveAsToolStripMenuItem.Enabled = enabled;
            SaveToolStripMenuItem.Enabled = enabled;
            
            UndoMenuItem.Enabled = enabled;
            RedoMenuItem.Enabled = enabled;

            SelectAllToolStripMenuItem.Enabled = enabled;
            CutToolStripMenuItem.Enabled = enabled;
            PasteToolStripMenuItem.Enabled = enabled;
            SelectFontToolStripMenuItem.Enabled = enabled;
            FindAndReplaceToolStripMenuItem.Enabled = enabled;
            InsertImageToolStripMenuItem.Enabled = enabled; 

            FontToolStripMenuItem.Enabled = enabled;
            ParagraphToolStripMenuItem.Enabled = enabled;
            BulletsToolStripMenuItem.Enabled = enabled;
            
            //Tool
            tbrNew.Enabled = enabled;
            tbrOpen.Enabled = enabled;
            tbrSave.Enabled = enabled;

            tbrBold.Enabled = enabled;
            tbrFont.Enabled = enabled;
            tbrItalic.Enabled = enabled;
            tbrBold.Enabled = enabled;
            tbrUnderline.Enabled = enabled; 

            tbrLeft.Enabled = enabled;
            tbrRight.Enabled = enabled;
            tbrCenter.Enabled = enabled;
            tspColor.Enabled = enabled;
        }

        private void OpenFile()
        {
            try
            {
                OpenFileDialog.Title = "Open File";
                OpenFileDialog.DefaultExt = "rtf";
                OpenFileDialog.Filter = "Rich Text Files|*.rtf|Text Files|*.txt|HTML Files|*.htm|All Files|*.*";
                OpenFileDialog.FilterIndex = 1;
                OpenFileDialog.FileName = string.Empty;

                if (OpenFileDialog.ShowDialog() == DialogResult.OK)
                {

                    if (OpenFileDialog.FileName == "")
                    {
                        return;
                    }

                    string strExt;
                    strExt = System.IO.Path.GetExtension(OpenFileDialog.FileName);
                    strExt = strExt.ToUpper();

                    if (strExt == ".RTF")
                    {
                        rtbDoc.LoadFile(OpenFileDialog.FileName, RichTextBoxStreamType.RichText);
                    }
                    else
                    {
                        System.IO.StreamReader txtReader;
                        txtReader = new System.IO.StreamReader(OpenFileDialog.FileName);
                        rtbDoc.Text = txtReader.ReadToEnd();
                        txtReader.Close();
                        txtReader = null;
                        rtbDoc.SelectionStart = 0;
                        rtbDoc.SelectionLength = 0;
                    }

                    myCurrentFile = OpenFileDialog.FileName;
                    rtbDoc.Modified = false;
                    this.Text = "Editor: " + myCurrentFile.ToString();
                }
                else
                {
                    MessageBox.Show("Open File request cancelled by user.", "Cancelled");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private bool SaveToFile(string fileName)
        {
            if (commonV2.StringLibs.IsNullOrEmpty(myCurrentFile)) return false;

            string strExt =  System.IO.Path.GetExtension(myCurrentFile);
            strExt = strExt.ToUpper();
            if (strExt != ".RTF") return false;
            rtbDoc.SaveFile(myCurrentFile, RichTextBoxStreamType.RichText);
            return true;
        }

        #region "Declaration"
        private string myCurrentFile;
        private int checkPrint;
        #endregion

        #region "Menu Methods"
        private void NewToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (rtbDoc.Modified == true)
                {
                    System.Windows.Forms.DialogResult answer;
                    answer = MessageBox.Show("Save current document before creating new document?", "Unsaved Document", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (answer == System.Windows.Forms.DialogResult.No)
                    {
                        myCurrentFile = "";
                        this.Text = "Editor: New Document";
                        rtbDoc.Modified = false;
                        rtbDoc.Clear();
                        return;
                    }
                    else
                    {
                        SaveToolStripMenuItem_Click(this, new EventArgs());
                        rtbDoc.Modified = false;
                        rtbDoc.Clear();
                        myCurrentFile = "";
                        this.Text = "Editor: New Document";
                        return;
                    }
                }
                else
                {
                    myCurrentFile = "";
                    this.Text = "Editor: New Document";
                    rtbDoc.Modified = false;
                    rtbDoc.Clear();
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void OpenToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (rtbDoc.Modified == true)
                {
                    System.Windows.Forms.DialogResult answer;
                    answer = MessageBox.Show("Save current file before opening another document?", "Unsaved Document", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (answer == System.Windows.Forms.DialogResult.No)
                    {
                        rtbDoc.Modified = false;
                        OpenFile();
                    }
                    else
                    {
                        SaveToolStripMenuItem_Click(this, new EventArgs());
                        OpenFile();
                    }
                }
                else
                {
                    OpenFile();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
       
        private void SaveToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (this.myOnSave != null)
                {
                    this.myOnSave(sender);
                    return;
                }

                if (commonV2.StringLibs.IsNullOrEmpty(myCurrentFile))
                {
                    SaveAsToolStripMenuItem_Click(this, e);
                    return;
                }
                try
                {
                    SaveToFile(myCurrentFile);
                    this.Text = "Save: " + myCurrentFile.ToString();
                    rtbDoc.Modified = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString(), "File Save Error");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void SaveAsToolStripMenuItem_Click(object sender, System.EventArgs e)
        {

            try
            {
                SaveFileDialog.Title = "Save File";
                SaveFileDialog.DefaultExt = "rtf";
                SaveFileDialog.Filter = "Rich Text Files|*.rtf|Text Files|*.txt|HTML Files|*.htm|All Files|*.*";
                SaveFileDialog.FilterIndex = 1;

                if (SaveFileDialog.ShowDialog() != DialogResult.OK) return;
                if (SaveFileDialog.FileName == "")          return;
                
                SaveToFile(SaveFileDialog.FileName);

                myCurrentFile = SaveFileDialog.FileName;
                rtbDoc.Modified = false;
                this.Text = "File : " + myCurrentFile.ToString();
                MessageBox.Show(myCurrentFile.ToString() + " saved.", "File Save");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }


        private void ExitToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (this.myOnExit == null) return;
                myOnExit(sender);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void SelectAllToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectAll();
            }
            catch (Exception)
            {
                MessageBox.Show("Unable to select all document content.", "Select", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void CopyToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.Copy();
            }
            catch (Exception)
            {
                MessageBox.Show("Unable to copy document content.", "Copy", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void CutToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.Cut();
            }
            catch
            {
                MessageBox.Show("Unable to cut document content.", "Cut", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void PasteToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.Paste();
            }
            catch
            {
                MessageBox.Show("Unable to copy clipboard content to document.", "Paste", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void lockEdMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                LockEdit(lockEdMenuItem.Checked);
            }
            catch
            {
                MessageBox.Show("LockEdit() error.", "LockEdit", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void wordWrapMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                rtbDoc.WordWrap = wordWrapMenuItem.Checked;
            }
            catch
            {
                MessageBox.Show("WordWrap() error.", "WordWrap", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SelectFontToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (!(rtbDoc.SelectionFont == null))
                {
                    FontDialog.Font = rtbDoc.SelectionFont;
                }
                else
                {
                    FontDialog.Font = null;
                }
                FontDialog.ShowApply = true;
                if (FontDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    rtbDoc.SelectionFont = FontDialog.Font;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void FontColorToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                ColorDialog.Color = rtbDoc.ForeColor;
                if (ColorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    rtbDoc.SelectionColor = ColorDialog.Color;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void BoldToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (!(rtbDoc.SelectionFont == null))
                {
                    System.Drawing.Font currentFont = rtbDoc.SelectionFont;
                    System.Drawing.FontStyle newFontStyle;

                    newFontStyle = rtbDoc.SelectionFont.Style ^ FontStyle.Bold;

                    rtbDoc.SelectionFont = new Font(currentFont.FontFamily, currentFont.Size, newFontStyle);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void ItalicToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (!(rtbDoc.SelectionFont == null))
                {
                    System.Drawing.Font currentFont = rtbDoc.SelectionFont;
                    System.Drawing.FontStyle newFontStyle;

                    newFontStyle = rtbDoc.SelectionFont.Style ^ FontStyle.Italic;

                    rtbDoc.SelectionFont = new Font(currentFont.FontFamily, currentFont.Size, newFontStyle);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void UnderlineToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (!(rtbDoc.SelectionFont == null))
                {
                    System.Drawing.Font currentFont = rtbDoc.SelectionFont;
                    System.Drawing.FontStyle newFontStyle;

                    newFontStyle = rtbDoc.SelectionFont.Style ^ FontStyle.Underline;

                    rtbDoc.SelectionFont = new Font(currentFont.FontFamily, currentFont.Size, newFontStyle);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void NormalToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (!(rtbDoc.SelectionFont == null))
                {
                    System.Drawing.Font currentFont = rtbDoc.SelectionFont;
                    System.Drawing.FontStyle newFontStyle;
                    newFontStyle = FontStyle.Regular;
                    rtbDoc.SelectionFont = new Font(currentFont.FontFamily, currentFont.Size, newFontStyle);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void PageColorToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                ColorDialog.Color = rtbDoc.BackColor;
                if (ColorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    rtbDoc.BackColor = ColorDialog.Color;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        
        private void mnuUndo_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (rtbDoc.CanUndo)
                {
                    rtbDoc.Undo();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void mnuRedo_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (rtbDoc.CanRedo)
                {
                    rtbDoc.Redo();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void LeftToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionAlignment = HorizontalAlignment.Left;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void CenterToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionAlignment = HorizontalAlignment.Center;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void RightToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionAlignment = HorizontalAlignment.Right;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        
        private void AddBulletsToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.BulletIndent = 10;
                rtbDoc.SelectionBullet = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void RemoveBulletsToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionBullet = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }

        private void mnuIndent0_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionIndent = 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void mnuIndent5_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionIndent = 5;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void mnuIndent10_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionIndent = 10;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void mnuIndent15_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionIndent = 15;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void mnuIndent20_Click(object sender, System.EventArgs e)
        {
            try
            {
                rtbDoc.SelectionIndent = 20;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }

        }


        commonV2.forms.rtfFind myFindForm = null;
        private void FindToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (myFindForm == null || myFindForm.IsDisposed)
                {
                    myFindForm = new commonV2.forms.rtfFind(rtbDoc);
                    myFindForm.TopMost = true;
                }
                myFindForm.Activate();
                myFindForm.Show();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        
        commonV2.forms.rtfReplace myFindAndReplaceForm = null;
        private void FindAndReplaceToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (myFindAndReplaceForm == null || myFindAndReplaceForm.IsDisposed)
                {
                    myFindAndReplaceForm = new commonV2.forms.rtfReplace(rtbDoc);
                    myFindAndReplaceForm.TopMost = true;
                }
                myFindAndReplaceForm.Activate();
                myFindAndReplaceForm.Show();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void PreviewToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                PrintPreviewDialog.Document = PrintDocument;
                PrintPreviewDialog.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void PrintToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            try
            {
                PrintDialog.Document = PrintDocument;
                if (PrintDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    PrintDocument.Print();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void mnuPageSetup_Click(object sender, System.EventArgs e)
        {
            try
            {
                PageSetupDialog.Document = PrintDocument;
                PageSetupDialog.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Error");
            }
        }
        private void InsertImageToolStripMenuItem_Click(object sender, System.EventArgs e)
        {

            OpenFileDialog.Title = "Insert Image File";
            OpenFileDialog.DefaultExt = "rtf";
            OpenFileDialog.Filter = "Bitmap Files|*.bmp|JPEG Files|*.jpg|GIF Files|*.gif";
            OpenFileDialog.FilterIndex = 1;
            OpenFileDialog.ShowDialog();

            if (OpenFileDialog.FileName == "")
            {
                return;
            }

            try
            {
                string strImagePath = OpenFileDialog.FileName;
                Image img;
                img = Image.FromFile(strImagePath);
                Clipboard.SetDataObject(img);
                DataFormats.Format df;
                df = DataFormats.GetFormat(DataFormats.Bitmap);
                if (this.rtbDoc.CanPaste(df))
                {
                    this.rtbDoc.Paste(df);
                }
            }
            catch
            {
                MessageBox.Show("Unable to insert image format selected.", "Paste", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void rtbDoc_SelectionChanged(object sender, EventArgs e)
        {
            tbrBold.Checked = rtbDoc.SelectionFont.Bold;
            tbrItalic.Checked = rtbDoc.SelectionFont.Italic;
            tbrUnderline.Checked = rtbDoc.SelectionFont.Underline;
        }

        #endregion

        #region Printing
        private void PrintDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            checkPrint = 0;

        }
        private void PrintDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            checkPrint = rtbDoc.Print(checkPrint, rtbDoc.TextLength, e);
            if (checkPrint < rtbDoc.TextLength)
            {
                e.HasMorePages = true;
            }
            else
            {
                e.HasMorePages = false;
            }
        }
        #endregion
    }
}